﻿using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace MASAS.Feature.Addons.WebParts.NotificationDashboard
{

    /// <summary>
    /// Class NotificationDashboardToolPart.
    /// </summary>
    class NotificationDashboardToolPart : ToolPart
    {

        // Private members...
        private UpdatePanel     _pnlMain;

        private Label           _lblList;
        private Label           _lblExpField;
        private Label           _lblTrackingField;
        private Label           _lblShowIgnored;
        private Label           _lblMessage;

        private DropDownList    _cbLists;
        private DropDownList    _cbExpFieldList;
        private DropDownList    _cbTrackingFieldList;
        private CheckBox        _checkShowIgnored;

        /// <summary>
        /// Initializes a new instance of the <see cref="NotificationDashboardToolPart"/> class.
        /// </summary>
        public NotificationDashboardToolPart()
        {
            Title = "Notification Dashboard";
        }

        /// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            // Create the controls for the settings...
            _pnlMain = new UpdatePanel();

            _pnlMain.ContentTemplateContainer.Controls.Add( new LiteralControl( "<b>Set List and Fields:</b>" ) );
            _pnlMain.ContentTemplateContainer.Controls.Add( new LiteralControl( "<br /><br />" ) );

            Table table = new Table();

            _lblList = new Label();
            _lblList.Text = "List:";
            _cbLists = new DropDownList();
            _cbLists.Width = Unit.Percentage( 100 );
            _cbLists.AutoPostBack = true;
            AddRowControls( table, _lblList, _cbLists );

            _lblExpField = new Label();
            _lblExpField.Text = "Expiration Field:";
            _cbExpFieldList = new DropDownList();
            _cbExpFieldList.Width = Unit.Percentage( 100 );
            AddRowControls( table, _lblExpField, _cbExpFieldList );

            _lblTrackingField = new Label();
            _lblTrackingField.Text = "State Field:";
            _cbTrackingFieldList = new DropDownList();
            _cbTrackingFieldList.Width = Unit.Percentage( 100 );
            AddRowControls( table, _lblTrackingField, _cbTrackingFieldList );

            _lblShowIgnored = new Label();
            _lblShowIgnored.Text = "Show Ignored:";
            _checkShowIgnored = new CheckBox();
            AddRowControls( table, _lblShowIgnored, _checkShowIgnored );

            _lblMessage = new Label();
            _lblMessage.Text = "";

            _pnlMain.ContentTemplateContainer.Controls.Add( table );
            _pnlMain.ContentTemplateContainer.Controls.Add( new LiteralControl( "<br/><br/>" ) );
            _pnlMain.ContentTemplateContainer.Controls.Add( _lblMessage );

            this.Controls.Add( _pnlMain );

            // Populate the controls...
            PopulateControls();

            // Enable the lists change event...
            _cbLists.SelectedIndexChanged += _cbLists_SelectedIndexChanged;

            // Call the base method...
            base.CreateChildControls();
        }

        /// <summary>
        /// Adds the row controls.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <param name="labelControl">The label control.</param>
        /// <param name="contentControl">The content control.</param>
        private void AddRowControls( Table table, Control labelControl, Control contentControl )
        {
            TableRow    row     = new TableRow();
            TableCell   cell    = new TableCell();

            // Add the "label" control...
            cell.Wrap = false;
            cell.Controls.Add( labelControl );
            row.Cells.Add( cell );

            // Add the content control...
            cell = new TableCell();
            cell.Wrap = false;
            cell.Controls.Add( contentControl );
            row.Cells.Add( cell );

            // Add the row to the table...
            table.Rows.Add( row );
        }

        /// <summary>
        /// Populates the controls.
        /// </summary>
        private void PopulateControls()
        {
            NotificationDashboard ndWebPart = (NotificationDashboard)this.ParentToolPane.SelectedWebPart;
            
            if( ndWebPart != null )
            {
                SPWeb web = SPControl.GetContextWeb( Context );

                SPList list = PopulateLists( web, ndWebPart.ListName );

                PopulateFields( list, ndWebPart.ExpirationFieldName, ndWebPart.TrackingFieldName );

                _cbLists.SelectedValue = ndWebPart.ListName;
                _cbExpFieldList.SelectedValue = ndWebPart.ExpirationFieldName;
                _cbTrackingFieldList.SelectedValue = ndWebPart.TrackingFieldName;
                _checkShowIgnored.Checked = ndWebPart.ShowIgnored;
            }
            else
            {
                _lblMessage.Text = "An unknown error has occurred: The selected web part cannot be found.";

                _cbLists.Enabled                = false;
                _cbExpFieldList.Enabled         = false;
                _cbTrackingFieldList.Enabled    = false;
                _checkShowIgnored.Enabled       = false;
            }
        }

        /// <summary>
        /// Populates the lists.
        /// </summary>
        /// <param name="web">The web.</param>
        /// <param name="listName">Name of the list.</param>
        /// <returns>SPList.</returns>
        private SPList PopulateLists( SPWeb web, string listName )
        {
            SPList selectedList = null;

            _cbLists.Items.Clear();

            foreach( SPList list in web.Lists )
            {
                _cbLists.Items.Add( list.Title );

                if( list.Title == listName )
                {
                    selectedList = list;
                }
            }

            _cbLists.SelectedValue = listName;

            return selectedList;
        }

        /// <summary>
        /// Populates the fields.
        /// </summary>
        /// <param name="list">The list.</param>
        /// <param name="expirationFieldName">Name of the expiration field.</param>
        /// <param name="trackingFieldName">Name of the tracking field.</param>
        private void PopulateFields( SPList list, string expirationFieldName = null, string trackingFieldName = null )
        {
            bool foundExpfield = false;
            bool foundTrackingField = false;

            _cbExpFieldList.Items.Clear();
            _cbTrackingFieldList.Items.Clear();

            // Add the compatible fields to the field combos.
            foreach( SPField field in list.Fields )
            {
                if( field.Type == SPFieldType.DateTime )
                {
                    // Only add Date/Time fields to the expiration combo box...
                    //_cbExpFieldList.Items.Add( field.Title );
                    _cbExpFieldList.Items.Add( field.InternalName );

                    foundExpfield = true;
                    //if( expirationFieldName != null && field.Title == expirationFieldName )
                    if( expirationFieldName != null && field.InternalName == expirationFieldName )
                    {
                        _cbExpFieldList.SelectedValue = expirationFieldName;
                    }
                }

                if( field.Type == SPFieldType.Text || field.Type == SPFieldType.Choice )
                {
                    // Only add Text and Choice fields to the tracking combo box...
                    //_cbTrackingFieldList.Items.Add( field.Title );
                    _cbTrackingFieldList.Items.Add( field.InternalName );

                    foundTrackingField = true;
                    //if( trackingFieldName != null && field.Title == trackingFieldName )
                    if( trackingFieldName != null && field.InternalName == trackingFieldName )
                    {
                        _cbTrackingFieldList.SelectedValue = trackingFieldName;
                    }
                }
            }

            _cbExpFieldList.Enabled         = foundExpfield;
            _cbTrackingFieldList.Enabled    = foundTrackingField;

            if( !foundExpfield || !foundTrackingField )
            {
                _lblMessage.Text = "Please select a list that contains an Expiration (Date/Time) field and a Tracking (Text or Choice) field.";
            }

        }

        /// <summary>
        /// Handles the SelectedIndexChanged event of the _cbLists control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        void _cbLists_SelectedIndexChanged( object sender, EventArgs e )
        {
            SPWeb web = SPControl.GetContextWeb( Context );

            SPList list = web.Lists.TryGetList( _cbLists.SelectedValue );
            if( list != null )
            {
                PopulateFields( list );
            }
            else
            {
                _lblMessage.Text = "An unknown error has occured: The selected list cannot be found.";
                _cbExpFieldList.Enabled         = false;
                _cbTrackingFieldList.Enabled    = false;
            }

        }

        /// <summary>
        /// Called when the user clicks the OK or the Apply button in the tool pane.
        /// </summary>
        public override void ApplyChanges()
        {
            NotificationDashboard ndWebPart = (NotificationDashboard)this.ParentToolPane.SelectedWebPart;

            ndWebPart.ShowIgnored = _checkShowIgnored.Checked;
            ndWebPart.ListName = _cbLists.SelectedValue;
            ndWebPart.ExpirationFieldName = _cbExpFieldList.SelectedValue;
            ndWebPart.TrackingFieldName = _cbTrackingFieldList.SelectedValue;
            ndWebPart.UpdateAttributes();

            // Call the base method...
            base.ApplyChanges();
        }

        /// <summary>
        /// When overridden in a derived class, this method is called after all other tool parts have called their ApplyChanges methods.
        /// </summary>
        public override void SyncChanges()
        {
            PopulateControls();

            // Call the base method...
            base.SyncChanges();
        }

    }

}
